برنامه نویسی با جمنای؛ آموزش کدنویسی React و دیباگ هوشمند

برنامه نویسی با جمنای؛ آموزش کدنویسی React و دیباگ هوشمند

هنوز امتیازی ثبت نشده
۱۴۰۵/۶/۱۷7 دقیقه مطالعه97 بازدید

برنامه نویسی با جمنای؛ آموزش کدنویسی React و دیباگ هوشمند

برنامه نویسی با جمنای فقط به این معنا نیست که یک درخواست مثل «برای من یک کامپوننت React بساز» بنویسید و خروجی را مستقیماً داخل پروژه قرار دهید. بیشترین ارزش Gemini زمانی ایجاد می‌شود که آن را مانند یک همکار فنی برای تحلیل ساختار پروژه، پیدا کردن علت خطا، بررسی State و Props، اصلاح Hookها، تولید تست و بازبینی کد به کار بگیرید. در این راهنما این فرایند را از تولید یک کامپوننت واقعی React تا دیباگ useEffect و Code Review بررسی می‌کنیم.

برنامه نویسی با جمنای دقیقاً یعنی چه؟

Gemini می‌تواند در بخش‌های مختلف چرخه توسعه نرم‌افزار نقش دستیار داشته باشد؛ از توضیح یک قطعه کد ناشناخته و تولید کامپوننت گرفته تا پیشنهاد Refactor، تحلیل پیام خطا و ساخت تست. بنابراین بهتر است آن را نه یک «ماشین تولید کد»، بلکه ابزاری برای سریع‌تر کردن فرایند فکر کردن، بررسی کردن و پیاده‌سازی در نظر بگیریم.

برای توسعه‌دهنده React، استفاده‌های کاربردی شامل ساخت کامپوننت، تبدیل منطق به JSX، نوشتن Hook، تحلیل خطای Console، بررسی dependencyهای useEffect، پیدا کردن رندرهای غیرضروری، طراحی ساختار State و تولید تست است.

نکته مهم هرچه Context دقیق‌تری در اختیار جمنای قرار دهید، احتمال دریافت پاسخ کاربردی‌تر بیشتر می‌شود. نسخه React، ابزار Build، کد مرتبط، متن کامل خطا و رفتار مورد انتظار را همراه درخواست ارسال کنید.

اگر قصد دارید قابلیت‌های دیگر Gemini را هم برای توسعه و بهره‌وری بشناسید، راهنمای قابلیت‌های Gemini Advanced برای توسعه‌دهندگان می‌تواند مکمل این آموزش باشد.

کدام ابزار جمنای برای برنامه نویسی مناسب‌تر است؟

عبارت «کدنویسی با Gemini» می‌تواند به چند محیط مختلف اشاره کند. انتخاب ابزار مناسب به اندازه پروژه، نوع وظیفه و میزان دسترسی Gemini به فایل‌های پروژه بستگی دارد.

مقایسه روش‌های استفاده از جمنای برای کدنویسی
محیط کاربرد مناسب مزیت اصلی مناسب برای
Gemini / Canvas نوشتن و ویرایش سریع کد تعامل ساده با زبان طبیعی نمونه کد، آموزش و مسائل محدود
Google AI Studio Build ساخت و اجرای Web App پروژه چندفایلی و Preview پروتوتایپ و اپلیکیشن React
Gemini Code Assist Standard / Enterprise کمک مستقیم داخل IDE Completion، Transformation و Chat پروژه‌های تیمی و سازمانی
Antigravity وظایف Agentic و چندمرحله‌ای کار روی فایل‌ها و فرایندهای پیچیده‌تر پروژه‌های واقعی توسعه نرم‌افزار

Google AI Studio در Build Mode امکان ساخت و ویرایش اپلیکیشن‌های وب از طریق Prompt را فراهم می‌کند و برای اپلیکیشن وب، فرانت‌اند React را به‌صورت پیش‌فرض ایجاد می‌کند. جزئیات این قابلیت را می‌توانید در مستندات رسمی Google AI Studio Build بررسی کنید.

توجه به آموزش‌های قدیمی Gemini ابزارها و پلن‌های توسعه‌دهندگان گوگل در طول زمان تغییر می‌کنند. اگر آموزش قدیمی درباره Gemini Code Assist for Individuals یا Gemini CLI مشاهده کردید، قبل از نصب یا خرید، وضعیت فعلی آن را در مستندات رسمی گوگل بررسی کنید.
دسترسی به Gemini برای استفاده حرفه‌ای

اگر برای کدنویسی، تحقیق یا استفاده از قابلیت‌های پیشرفته Gemini به حساب مناسب نیاز دارید، می‌توانید شرایط اکانت‌های موجود ویپک را بررسی کنید.

مشاهده و خرید اکانت Gemini ویپک

آموزش برنامه نویسی با جمنای برای ساخت کد React

یکی از اشتباه‌های رایج این است که ساخت یک پروژه کامل را با یک جمله کوتاه به مدل بسپاریم. در پروژه واقعی، بهتر است مسئله را به چند مرحله کوچک‌تر تقسیم کنید.

  1. Stack پروژه را مشخص کنید.
    مثلاً بنویسید پروژه با React، Vite، JavaScript یا TypeScript ساخته شده و برای استایل از Tailwind CSS استفاده می‌کنید.
  2. هدف کامپوننت را توضیح دهید.
    دقیقاً مشخص کنید کاربر چه کاری انجام می‌دهد و کامپوننت چه داده‌ای دریافت یا تولید می‌کند.
  3. محدودیت‌ها را مشخص کنید.
    مانند استفاده نکردن از کتابخانه جانبی، رعایت Accessibility یا جلوگیری از Request غیرضروری.
  4. ابتدا معماری را بخواهید.
    قبل از تولید کد، از Gemini بخواهید Stateها، Componentها و جریان داده را مشخص کند.
  5. پیاده‌سازی را مرحله‌ای انجام دهید.
    کامپوننت پایه، Fetch، Error Handling، Loading، تست و Optimization را در مراحل جدا اضافه کنید.

نمونه پرامپت برای ساخت کامپوننت React

من یک پروژه React با Vite و JavaScript دارم. یک کامپوننت ProductSearch بساز که: - یک input برای جستجو داشته باشد. - هنگام تایپ کاربر درخواست‌های غیرضروری ارسال نکند. - Loading و Error state داشته باشد. - اگر نتیجه‌ای نبود پیام مناسب نشان دهد. - کد ساده و قابل نگهداری باشد. - از کتابخانه جانبی استفاده نکن. ابتدا ساختار Stateها و منطق کامپوننت را توضیح بده. بعد کد کامل را بنویس. در پایان ۳ خطای احتمالی این پیاده‌سازی را هم بررسی کن.

مثال واقعی: ساخت ProductSearch با Debounce در React

برای اینکه آموزش صرفاً به Prompt محدود نشود، یک نمونه واقعی را بررسی می‌کنیم. در این کامپوننت کاربر نام محصول را تایپ می‌کند، اما Request بلافاصله بعد از هر کلید ارسال نمی‌شود. یک Debounce کوتاه باعث می‌شود Fetch پس از توقف تایپ اجرا شود.

import { useEffect, useState } from 'react';

export default function ProductSearch() {
  const [query, setQuery] = useState('');
  const [products, setProducts] = useState([]);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState('');

  useEffect(() => {
    const normalizedQuery = query.trim();

    if (!normalizedQuery) {
      setProducts([]);
      setError('');
      setLoading(false);
      return;
    }

    const controller = new AbortController();

    const timer = setTimeout(async () => {
      try {
        setLoading(true);
        setError('');

        const response = await fetch(
          `/api/products?q=${encodeURIComponent(normalizedQuery)}`,
          { signal: controller.signal }
        );

        if (!response.ok) {
          throw new Error('دریافت اطلاعات محصولات ناموفق بود.');
        }

        const data = await response.json();
        setProducts(Array.isArray(data) ? data : []);
      } catch (err) {
        if (err.name !== 'AbortError') {
          setError(err.message || 'خطایی رخ داد.');
          setProducts([]);
        }
      } finally {
        if (!controller.signal.aborted) {
          setLoading(false);
        }
      }
    }, 400);

    return () => {
      clearTimeout(timer);
      controller.abort();
    };
  }, [query]);

  return (
    <section>
      <label htmlFor="product-search">
        جستجوی محصول
      </label>

      <input
        id="product-search"
        value={query}
        => setQuery(event.target.value)}
        placeholder="نام محصول را وارد کنید"
      />

      {loading && <p>در حال جستجو...</p>}

      {error && (
        <p role="alert">{error}</p>
      )}

      {!loading &&
        !error &&
        query.trim() &&
        products.length === 0 && (
          <p>محصولی پیدا نشد.</p>
        )}

      <ul>
        {products.map((product) => (
          <li key={product.id}>
            {product.name}
          </li>
        ))}
      </ul>
    </section>
  );
}

این نمونه چند مفهوم مهم را هم‌زمان پوشش می‌دهد: useState برای مدیریت Query و وضعیت رابط کاربری، useEffect برای واکنش به تغییر جستجو، setTimeout برای Debounce و AbortController برای متوقف کردن Request قبلی هنگام تغییر Query یا Unmount شدن کامپوننت.

چرا Cleanup مهم است؟ اگر کاربر قبل از پایان ۴۰۰ میلی‌ثانیه دوباره تایپ کند، Timer قبلی حذف می‌شود. اگر Request قبلاً شروع شده باشد، AbortController تلاش می‌کند آن Request را متوقف کند. به این ترتیب احتمال نمایش نتیجه قدیمی و مصرف بی‌دلیل شبکه کاهش پیدا می‌کند.

دیباگ React با جمنای؛ روش درست پیدا کردن خطا

برای Debug، ارسال جمله‌ای مانند «این کد کار نمی‌کند، درستش کن» معمولاً Context کافی در اختیار مدل قرار نمی‌دهد. یک گزارش خطای مناسب برای Gemini تقریباً همان اطلاعاتی را دارد که برای یک همکار برنامه‌نویس ارسال می‌کنید.

برای هر نوع خطا چه اطلاعاتی به جمنای بدهیم؟
نوع مشکل اطلاعات ضروری سوال پیشنهادی اشتباه رایج
Runtime Error متن کامل Error و Stack Trace اول علت را مشخص کن، سپس Fix بده ارسال فقط آخرین خط خطا
Infinite Render State، Effect و dependencyها چه چیزی State را مداوم تغییر می‌دهد؟ حذف تصادفی dependency
API / Fetch Status Code، Response و Network Log مشکل Frontend است یا API؟ فرض اینکه همه خطاها از React هستند
UI اشتباه Props، State و خروجی مورد انتظار جریان داده را مرحله‌به‌مرحله تحلیل کن ارسال فقط JSX
Performance کامپوننت‌های درگیر و علت Render قبل از Memoization علت Render را پیدا کن استفاده بی‌دلیل از memo و useMemo

قالب پیشنهادی گزارش خطا به Gemini

Environment: React + Vite JavaScript Browser: Chrome Problem: بعد از تغییر فیلتر، کامپوننت چند بار پشت سر هم Fetch انجام می‌دهد. Expected behavior: فقط یک Request بعد از تغییر فیلتر ارسال شود. Actual behavior: Request چند بار تکرار می‌شود. Console: [متن کامل خطا یا Log] Relevant code: [کامپوننت و Hookهای مرتبط] لطفاً: 1. ابتدا Root Cause را توضیح بده. 2. مشخص کن کدام خط دقیقاً مشکل دارد. 3. کمترین تغییر لازم را پیشنهاد بده. 4. عارضه جانبی احتمالی Fix را مشخص کن. 5. نسخه نهایی کد را ارائه کن.

مثال عملی: پیدا کردن حلقه useEffect با Gemini

فرض کنید در یک کامپوننت React کدی شبیه نمونه زیر دارید:

const [users, setUsers] = useState([]);

useEffect(() => {
  fetch('/api/users')
    .then(response => response.json())
    .then(data => setUsers(data));
}, [users]);

در این مثال Effect به users وابسته است، اما داخل همان Effect با setUsers مقدار users تغییر می‌کند. تغییر State می‌تواند Render جدید ایجاد کند و تغییر dependency نیز Effect را دوباره اجرا کند؛ در نتیجه چرخه تکراری ایجاد می‌شود.

این useEffect را مرحله‌به‌مرحله تحلیل کن. می‌خواهم بدانم: - اولین Render چه اتفاقی می‌افتد؟ - چه چیزی Effect را اجرا می‌کند؟ - setUsers چگونه Render بعدی را ایجاد می‌کند؟ - dependency array چه نقشی در تکرار Request دارد؟ - کمترین Fix امن چیست؟ - آیا React StrictMode می‌تواند تعداد اجراها را در Development متفاوت نشان دهد؟

برای یک Fetch اولیه ساده، نسخه اصلاح‌شده می‌تواند شبیه نمونه زیر باشد:

useEffect(() => {
  fetch('/api/users')
    .then(response => {
      if (!response.ok) {
        throw new Error('Request failed');
      }

      return response.json();
    })
    .then(data => setUsers(data))
    .catch(error => {
      console.error(error);
    });
}, []);

البته خالی کردن dependency array یک راه‌حل عمومی برای همه مشکلات useEffect نیست. dependencyها باید بر اساس مقادیری که Effect واقعاً استفاده می‌کند تعیین شوند.

StrictMode را با Infinite Loop اشتباه نگیرید React در محیط Development و زیر StrictMode برخی منطق‌ها و Effectها را عمداً دوباره اجرا می‌کند تا مشکلاتی مانند Side Effect ناسالم یا Cleanup ناقص آشکار شوند. حذف StrictMode نباید اولین راه‌حل برای رفع چنین رفتاری باشد.

برای بررسی رفتار رسمی این قابلیت، مستندات React StrictMode و همچنین مستندات useEffect منابع مناسبی هستند.

بهترین روش پرامپت‌نویسی برای برنامه نویسی با جمنای

کیفیت پاسخ مدل تا حد زیادی به نحوه تعریف مسئله وابسته است. برای مسائل برنامه‌نویسی می‌توانید Prompt را بر اساس پنج بخش اصلی تنظیم کنید.

Context + Problem + Evidence + Constraints + Output

  • Context: تکنولوژی، نسخه، ساختار پروژه و فایل درگیر
  • Problem: مشکل دقیق چیست؟
  • Evidence: Error، Log، Stack Trace یا رفتار مشاهده‌شده
  • Constraints: چه چیزهایی نباید تغییر کند؟
  • Output: دقیقاً چه خروجی‌ای می‌خواهید؟

پرامپت ضعیف

این کد React خرابه. درستش کن.

پرامپت بهتر

این کامپوننت React بعد از هر تایپ کاربر دوباره API را فراخوانی می‌کند. هدف: Request فقط 400 میلی‌ثانیه بعد از توقف تایپ ارسال شود. محدودیت: - کتابخانه جدید اضافه نکن. - API فعلی تغییر نکند. - ساختار JSX تا حد ممکن حفظ شود. قبل از اصلاح، علت Requestهای اضافی را توضیح بده. سپس کمترین تغییر ممکن را ارائه کن و Cleanup لازم را هم بررسی کن.

از Gemini بخواهید فرضیاتش را مشخص کند

گاهی مدل به دلیل Context ناقص مجبور به فرض کردن نسخه کتابخانه، ساختار API یا رفتار یک تابع می‌شود. اضافه کردن جمله‌ای مانند «اگر اطلاعات کافی نیست، فرضیاتت را قبل از Fix مشخص کن» باعث می‌شود این بخش شفاف‌تر شود.

چه مشکلاتی در React را می‌توان با جمنای سریع‌تر تحلیل کرد؟

۱. مشکل State و Props

وقتی رابط کاربری مقدار قدیمی یا غیرمنتظره نشان می‌دهد، State فعلی، Props ورودی و محل تغییر State را ارسال کنید و از Gemini بخواهید جریان داده را از Parent تا Child تحلیل کند.

۲. مشکل useEffect

Effectهای دارای dependency اشتباه، Cleanup ناقص یا State Updateهای زنجیره‌ای از رایج‌ترین نقاط مناسب برای تحلیل مرحله‌ای هستند.

۳. خطای undefined و null

اگر با خطای دسترسی به Property یک مقدار undefined مواجه هستید، علاوه بر خط خطادار، منبع داده و مقدار اولیه State را هم ارسال کنید. اضافه کردن Optional Chaining به‌تنهایی ممکن است فقط علامت مشکل را مخفی کند.

۴. مشکل Fetch و Async

از Gemini بخواهید خطای Network را از خطای Parsing، Status HTTP و مشکل State Management تفکیک کند تا بخش اشتباه پروژه اصلاح نشود.

۵. رندرهای غیرضروری

قبل از استفاده از React.memo، useMemo یا useCallback، علت Render را پیدا کنید. Optimization بدون شناخت Root Cause می‌تواند فقط پیچیدگی کد را افزایش دهد.

استفاده از Gemini برای تست و Code Review

یکی از کاربردهای مهم جمنای بعد از تولید یا اصلاح کد، تبدیل آن به Reviewer دوم است. به جای پرسیدن «این کد خوب است؟»، معیارهای بررسی را مشخص کنید.

این کامپوننت React را مثل یک Senior Frontend Engineer بررسی کن. فقط مشکلات واقعی را در این دسته‌ها گزارش کن: 1. Bug 2. State Management 3. Performance 4. Accessibility 5. Error Handling 6. Security 7. Maintainability برای هر مورد: - شدت را Low / Medium / High مشخص کن. - دلیل را توضیح بده. - Fix حداقلی ارائه کن. اگر موردی در یک دسته وجود ندارد، چیزی اختراع نکن.

Test Caseهای پیشنهادی برای ProductSearch

  • نمایش Loading هنگام شروع Request
  • نمایش نتایج پس از پاسخ موفق API
  • نمایش Empty State در صورت خالی بودن نتیجه
  • نمایش پیام مناسب هنگام خطای API
  • ارسال نشدن Request قبل از پایان Debounce
  • لغو Timer قبلی با تغییر Query
  • لغو Request قبلی هنگام Unmount یا Query جدید

پرامپت ساخت تست با Vitest و React Testing Library

برای کامپوننت ProductSearch بالا تست بنویس. Stack: - React - Vite - Vitest - React Testing Library سناریوها: 1. تایپ کاربر 2. Debounce چهارصد میلی‌ثانیه‌ای 3. Loading 4. پاسخ موفق API 5. Empty State 6. خطای API 7. تغییر Query قبل از پایان Timer 8. Unmount شدن کامپوننت قبل از نوشتن تست‌ها، توضیح بده کدام رفتارها باید Mock شوند. از تست کردن جزئیات داخلی implementation خودداری کن و رفتار قابل مشاهده کاربر را تست کن.

چک‌لیست برنامه نویسی با جمنای

  1. نسخه React و Stack پروژه را مشخص کنید.
  2. مشکل را با یک جمله دقیق تعریف کنید.
  3. Error، Stack Trace یا Log واقعی را ارسال کنید.
  4. فقط Context مرتبط را در اختیار مدل بگذارید.
  5. قبل از Fix، Root Cause را درخواست کنید.
  6. کمترین تغییر امن را بخواهید.
  7. کد تولیدشده را دستی Review کنید.
  8. Test، Lint و Build را اجرا کنید.

این ساختار باعث می‌شود استفاده از Gemini از یک فرایند آزمون‌وخطای تصادفی به یک Workflow قابل بررسی تبدیل شود.

محدودیت‌ها و نکات امنیتی هنگام کدنویسی با Gemini

خروجی هوش مصنوعی باید همانند کدی که از یک منبع بیرونی دریافت کرده‌اید بررسی شود. تولید شدن کد توسط مدل به معنی صحیح، امن یا مناسب بودن آن برای معماری پروژه شما نیست.

  • API Key، Token، Password و Secret واقعی را داخل Prompt قرار ندهید.
  • قبل از نصب Package پیشنهادی، نام، منبع و نگهداری آن را بررسی کنید.
  • دستورات Terminal تولیدشده را قبل از اجرا بخوانید.
  • Authentication، Payment و Permission را دستی Review کنید.
  • پس از هر Fix تست و Build پروژه را اجرا کنید.
  • از مدل بخواهید دلیل تغییرات را توضیح دهد، نه اینکه فقط فایل نهایی تولید کند.

اگر در اپلیکیشن خود از Gemini API استفاده می‌کنید، Secret یا API Key را بدون دلیل داخل کد Client قرار ندهید و معماری مناسب سمت سرور را برای اطلاعات حساس در نظر بگیرید.

جمع‌بندی؛ آیا برنامه نویسی با جمنای واقعاً کاربردی است؟

برنامه نویسی با جمنای زمانی بیشترین ارزش را دارد که Gemini را به‌عنوان دستیار تحلیل، دیباگ، تست و بازبینی استفاده کنید؛ نه جایگزینی برای درک React. مدل می‌تواند یک کامپوننت تولید کند، اما در پروژه واقعی هنوز باید بدانید State از کجا می‌آید، Effect چرا اجرا می‌شود، Request چه زمانی ارسال می‌شود و هر تغییر چه اثری روی بخش‌های دیگر دارد.

اگر تازه شروع کرده‌اید، یک کامپوننت کوچک مانند ProductSearch را انتخاب کنید، Context کامل به جمنای بدهید و از آن بخواهید قبل از کدنویسی معماری و نقاط شکست احتمالی را توضیح دهد. توسعه‌دهندگان باتجربه‌تر نیز معمولاً از Debugging، Refactoring، Test Generation و Code Review بیشترین استفاده را می‌برند.

بهترین نتیجه زمانی حاصل می‌شود که سرعت هوش مصنوعی با مستندات رسمی، بررسی انسانی، تست و ابزارهای واقعی توسعه ترکیب شود.

استفاده حرفه‌ای از Gemini را شروع کنید

برای بررسی پلن‌ها و شرایط دسترسی به Gemini می‌توانید صفحه اختصاصی این سرویس در ویپک را مشاهده کنید.

خرید اکانت جمنای ویپک

سوالات متداول درباره برنامه نویسی با جمنای

آیا برنامه نویسی با جمنای برای React مناسب است؟
بله. Gemini می‌تواند برای ساخت کامپوننت React، توضیح ساختار State و Props، بررسی Hookها، تحلیل خطا، Refactor و تولید تست استفاده شود. با این حال بهتر است خروجی مدل را کد نهایی تلقی نکنید. هر تغییر باید با معماری پروژه، مستندات React، تست و بررسی انسانی تطبیق داده شود.
برای دیباگ React چه چیزی به Gemini بفرستیم؟
نسخه و Stack پروژه، متن کامل Error، Stack Trace یا Log، رفتار مورد انتظار، رفتار واقعی و قطعه کد مرتبط را ارسال کنید. اگر مشکل به API مربوط است، Status Code و پاسخ Network نیز مفید است. Context دقیق معمولاً بهتر از ارسال حجم زیادی از فایل‌های نامرتبط عمل می‌کند.
آیا دو بار اجرا شدن useEffect همیشه نشانه باگ است؟
خیر. در محیط Development، React StrictMode می‌تواند Effectها را برای پیدا کردن مشکلات Cleanup و Side Effect دوباره اجرا کند. با این حال اجرای مداوم و بدون توقف معمولاً نیاز به بررسی dependencyها و State Update دارد. بنابراین ابتدا باید مشخص شود رفتار از StrictMode است یا یک حلقه واقعی در منطق برنامه.
Google AI Studio برای ساخت پروژه React مناسب است؟
Google AI Studio Build برای ساخت سریع نمونه‌های وب و اپلیکیشن‌های مبتنی بر Gemini کاربردی است و امکان تولید و ویرایش پروژه از طریق Prompt را فراهم می‌کند. برای پروژه Production همچنان لازم است معماری، امنیت، Secretها، وابستگی‌ها و کد تولیدشده به‌صورت مستقل بررسی شوند.
آیا می‌توان کد تولیدشده توسط Gemini را بدون بررسی استفاده کرد؟
توصیه نمی‌شود. مدل ممکن است API منسوخ، Package نامناسب، فرض اشتباه درباره ساختار پروژه یا راه‌حلی با عارضه جانبی پیشنهاد کند. کد تولیدشده باید از نظر منطق، امنیت، Performance، Accessibility و سازگاری با نسخه‌های واقعی پروژه بررسی و سپس با Test، Lint و Build تأیید شود.
بهترین پرامپت برای دیباگ با جمنای چیست؟
یک پرامپت خوب باید Context پروژه، مشکل دقیق، Evidence مانند Error و Log، محدودیت‌های تغییر و خروجی مورد انتظار را مشخص کند. بهتر است از Gemini بخواهید ابتدا Root Cause را توضیح دهد، سپس کمترین Fix ممکن را پیشنهاد کند و در پایان عوارض جانبی احتمالی راه‌حل را نیز بررسی کند.
اشتراک‌گذاری این مقاله:

نظرات کاربران